package com.mxchip.livestar.original;

import android.util.Log;

import com.mxchip.livestar.base.SystemData;
import com.mxchip.livestar.ui.call.AVDevice;
import com.mxchip.livestar.ui.call.AVPacket;
import com.mxchip.livestar.utils.MyLog;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * 发送音频数据辅助类
 */
public class SendAudioUtil {
    private SendAudioUtil() {
    }

    static SendAudioUtil util = new SendAudioUtil();

    public static SendAudioUtil getInstance() {
        return util;
    }

    private int audioLength = 10;
    private ArrayBlockingQueue<AVPacket> audioQueue = new ArrayBlockingQueue<>(audioLength);
    private SendThread thread = new SendThread();

    private boolean isStart;
    long t1;
    long t2;
    int total = 0;
    int size = 0;
    long lastPutDataTime = 0;

    public void start() {
        Log.d(TAG, "start: ");
        isStart = true;
        thread.start();
    }

    public void putSendData(@NotNull AVPacket data) {
        if (!isStart) return;

        size = (size + 1) % 3;
        if (size == 0) {
            MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendAudioUtil::putData per mill sec ++++++++++++++++++++++++++=======================**************************");
        }
        MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendAudioUtil::putData per mill sec : " + (System.currentTimeMillis() - lastPutDataTime) + "=======================" + "putData: audioQueue.size()" + audioQueue.size());

        lastPutDataTime = System.currentTimeMillis();
        try {
            audioQueue.put(data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    class SendThread extends Thread {
        AVPacket data = null;
        GetAudioData callBack;

        public void setCallback(GetAudioData callBack) {
            this.callBack = callBack;
        }

        @Override
        public void run() {
            super.run();
            while (isStart) {
                try {
//                    AVPacket data = audioQueue.take();
//                    FIleManager.write(data.getData());

                     sendDataPer18mil();
//                    sendDataPer54mil();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        int num = 0;
        int sleepTime = 0;
        int group = 60;
        int interval = 20;

        private void sendDataPer54mil() throws InterruptedException {
            total += t2;
            num = (num + 1) % 3;
            if (num == 2) {
                if (audioQueue.size() < 10) {
                    group = 66;
                } else {
                    group = 54;
                }
                if (total < group) {
                    sleepTime = group - total;
                    sleepTime = sleepTime > 0 ? sleepTime - 1 : 0;
                    Thread.sleep(sleepTime);
                }
                MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendThread::sendDataPer54mil: group--------------"
                        + " sleepTime:" + sleepTime
                        + " total:" + total
                        + " group:" + group
                        + " group-total=" + (group - total));
                total = 0;
            }
            MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendThread::sendDataPer54mil: group child" + " t2:" + t2 + " total:" + total);

            if (num == 0) {
                MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendThread::sendDataPer54mil: per mill sec ++++++++++++++++++++++++++=======================**************************");
            }
            MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendThread::sendDataPer54mil: per mill sec : " + (System.currentTimeMillis() - t1) + "======================= " + " audioQueue:" + audioQueue.size());
//            while (audioQueue.size() < 5) {
//                Thread.sleep(5);
//            }
            t1 = System.currentTimeMillis();
            data = audioQueue.take();
            if (callBack != null) {
                callBack.getAudioData(data);
            }
            if (t1 != 0)
                t2 = System.currentTimeMillis() - t1;

        }

        private void sendDataPer18mil() throws InterruptedException {
            total += t2;
            int sleepTime = 0;
            if (audioQueue.size() < 6) {
                interval = 20;
            } else {
                interval = 18;
            }
            if (interval > total) {
                sleepTime = interval - 1 - total;
                MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendAudioUtil.SendThread::20 > total "
                        + " total:" + total
                        + " t2:" + t2
                        + " sleepTime:" + sleepTime
                        + " interval:" + interval
                        + " audioQueue.size():" + audioQueue.size());
            }
            total = 0;
            Thread.sleep(sleepTime);
            if (t1 != 0) {
                MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendAudioUtil.SendThread:: per time: " + (System.currentTimeMillis() - t1));
            }
            t1 = System.currentTimeMillis();
            data = audioQueue.take();
            if (callBack != null && data != null) {
//                FIleManager.write(data.getData());
                callBack.getAudioData(data);
            }
            if (t1 != 0)
                t2 = System.currentTimeMillis() - t1;
        }
    }

    private static final String TAG = "SendAudioUtil";

    public void setGetAudioData(GetAudioData callBack) {
        Log.d(TAG, "setGetAudioData: ");
        if (!isStart){
            thread = new SendThread();
        }
        thread.setCallback(callBack);
    }

    public interface GetAudioData {
        void getAudioData(AVPacket data);
    }

    public void clear() {
        thread.setCallback(null);
        isStart = false;
        thread.interrupt();
        try {
            audioQueue.put(new AVPacket( new byte[640], AVDevice.AUDIO_BUILD_IN, SystemData.userId()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        audioQueue.clear();
        MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendAudioUtil::stop: audioQueue.size():" + audioQueue.size());
        while (!audioQueue.isEmpty()) {
            audioQueue.remove();
        }
        MyLog.logD(MyLog.AUDIO_SEND_MODEL, "SendAudioUtil::stop: audioQueue.size():" + audioQueue.size());
        t1 = 0;
        t2 = 0;
        total = 0;


    }

}
